

package jetbrains.buildServer.server.rest.model.nodes;

import com.google.common.collect.Iterables;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import jetbrains.buildServer.server.rest.model.Fields;
import jetbrains.buildServer.server.rest.swagger.annotations.ModelDescription;
import jetbrains.buildServer.server.rest.util.ValueWithDefault;
import jetbrains.buildServer.serverSide.NodeResponsibility;
import jetbrains.buildServer.serverSide.TeamCityNode;
import org.jetbrains.annotations.NotNull;

import static java.util.stream.Collectors.toList;

@XmlRootElement(name = "disabledResponsibilities")
@ModelDescription(
  value = "Represents a set of responsibilities that are currently disabled but can be enabled on a TeamCity node.",
  externalArticleLink = "https://www.jetbrains.com/help/teamcity/multinode-setup.html",
  externalArticleName = "Multi-node setup"
)
public class DisabledResponsibilities {
  @XmlAttribute
  public Integer count;

  @XmlElement(name = "responsibility")
  public List<Responsibility> responsibilities;

  public DisabledResponsibilities() {
  }

  public DisabledResponsibilities(@NotNull final TeamCityNode node, @NotNull final Fields fields) {
    Set<NodeResponsibility> enabledResponsibilities = node.getEnabledResponsibilities();
    Set<NodeResponsibility> disabledResponsibilities = NodeResponsibility.assignableResponsibilities().stream().filter(n -> !enabledResponsibilities.contains(n)).collect(Collectors.toSet());
    this.responsibilities = ValueWithDefault.decideDefault(fields.isIncluded("responsibility", true), () ->
      disabledResponsibilities.stream().map(toResponsibility(fields)).collect(toList())
    );
    this.count = ValueWithDefault.decideIncludeByDefault(fields.isIncluded("count"), Iterables.size(disabledResponsibilities));
  }

  @NotNull
  private Function<NodeResponsibility, Responsibility> toResponsibility(final @NotNull Fields fields) {
    return r -> new Responsibility(r, fields.getNestedField("responsibility", Fields.SHORT, Fields.LONG));
  }
}